/**
 * Notes: 预约后台管理
 * Ver : CCMiniCloud Framework 2.0.1 ALL RIGHTS RESERVED BY www.code3721.com
 * Date: 2021-12-08 07:48:00 
 */

const BaseAdminService = require('./base_admin_service.js');
const MeetService = require('../meet_service.js');
const dataUtil = require('../../../framework/utils/data_util.js');
const timeUtil = require('../../../framework/utils/time_util.js');
const util = require('../../../framework/utils/util.js');
const cloudUtil = require('../../../framework/cloud/cloud_util.js');
const cloudBase = require('../../../framework/cloud/cloud_base.js');

const MeetModel = require('../../model/meet_model.js');
const JoinModel = require('../../model/join_model.js');
const DayModel = require('../../model/day_model.js');
const config = require('../../../config/config.js');

class AdminMeetService extends BaseAdminService {

	/** 预约数据列表 */
	async getDayList(meetId, start, end) {
		let where = {
			DAY_MEET_ID: meetId,
			day: ['between', start, end]
		}
		let orderBy = {
			day: 'asc'
		}
		return await DayModel.getAllBig(where, 'day,times,dayDesc', orderBy);
	}

	// 按项目统计人数
	async statJoinCntByMeet(meetId) {
		let today = timeUtil.time('Y-M-D');
		let where = {
			day: ['>=', today],
			DAY_MEET_ID: meetId
		}

		let meetService = new MeetService();
		let list = await DayModel.getAllBig(where, 'DAY_MEET_ID,times', {}, 1000);
		for (let k in list) {
			let meetId = list[k].DAY_MEET_ID;
			let times = list[k].times;

			for (let j in times) {
				let timeMark = times[j].mark;
				meetService.statJoinCnt(meetId, timeMark);
			}
		}
	}

	/** 自助签到码 */
	async genSelfCheckinQr(page, timeMark) {
		return;
	}

	/** 管理员按钮核销 */
	async checkinJoin(joinId, flag) {
        let where = {
            _id: joinId
        }
        let data = {};
        data.JOIN_IS_CHECKIN = flag;
        await JoinModel.edit(where,data);
	}

	/** 管理员扫码核销 */
	async scanJoin(meetId, code) {
        let where = {
            JOIN_MEET_ID: meetId,
            JOIN_CODE :code
        }
        let fields = '*';
        let join = await  JoinModel.getOne(where,fields);
        if(join === null || join === undefined){
            this.AppError('预约码核销错误，请重新扫码');
            return;
		}
        if(!(join.JOIN_STATUS ==1)){
            this.AppError('预约已取消，请先预约后再核销');
            return;
		}
        if(join.JOIN_IS_CHECKIN == 1){
            this.AppError('此预约名单已核销，请勿重复核销');
            return;
		}
        let data = {};
        data.JOIN_IS_CHECKIN = 1;
        await JoinModel.edit(where,data);
	}

	/**
	 * 判断本日是否有预约记录
	 * @param {*} daySet daysSet的节点
	 */
	checkHasJoinCnt(times) {
		if (!times) return false;
		for (let k in times) {
			if (times[k].stat.succCnt) return true;
		}
		return false;
	}

	// 判断含有预约的日期
	getCanModifyDaysSet(daysSet) {
		let now = timeUtil.time('Y-M-D');

		for (let k in daysSet) {
			if (daysSet[k].day < now) continue;
			daysSet[k].hasJoin = this.checkHasJoinCnt(daysSet[k].times);
		}

		return daysSet;
	}

	/** 取消某个时间段的所有预约记录 */
	async cancelJoinByTimeMark(admin, meetId, timeMark, reason) {
        let where = {
            JOIN_MEET_ID: meetId,
            JOIN_MEET_TIME_MARK : timeMark
        }
        let data = {};
        data.JOIN_EDIT_ADMIN_ID = admin.ADMIN_ID;
        data.JOIN_EDIT_ADMIN_NAME = admin.ADMIN_NAME;
        data.JOIN_EDIT_ADMIN_STATUS = JoinModel.STATUS.CANCEL;
        data.JOIN_EDIT_ADMIN_TIME = timeUtil.time();
        data.JOIN_STATUS = JoinModel.STATUS.CANCEL;
        data.JOIN_REASON = reason;
        await JoinModel.edit(where,data);
        return this.statJoinCnt2(meetId, timeMark);
	}


	/**添加 */
	async insertMeet(adminId, {
		title,
		order,
		typeId,
		typeName,
		daysSet,
		isShowLimit,
		formSet,
	}) {
        let data ={
            MEET_ADMIN_ID:adminId,
            MEET_TYPE_ID : typeId,
            MEET_TYPE_NAME :typeName,
            MEET_DAYS : daysSet,
            MEET_TITLE: title,
            MEET_ORDER: order,
            MEET_IS_SHOW_LIMIT: isShowLimit,
            MEET_FORM_SET:formSet
        }
        let  _id = await MeetModel.insert(data);
        data.id = _id;
        let days = [];
        for (let k in daysSet) {
            let node = {};
            node.DAY_MEET_ID = _id;
            node.day = daysSet[k].day;
            node.dayDesc = daysSet[k].dayDesc;
            let times = [];
            for (let j in daysSet[k].times) {
                let timeNode = {};
                timeNode.mark = daysSet[k].times[j].mark;
                timeNode.start = daysSet[k].times[j].start;
                timeNode.end = daysSet[k].times[j].end;
                timeNode.isLimit = daysSet[k].times[j].isLimit;
                timeNode.limit = daysSet[k].times[j].limit;
                timeNode.status = daysSet[k].times[j].status;
                timeNode.stat = {
                    succCnt: daysSet[k].times[j].stat.succCnt,
                    cancelCnt: daysSet[k].times[j].stat.cancelCnt,
                    adminCancelCnt: daysSet[k].times[j].stat.adminCancelCnt
                };
                times.push(timeNode);
            }
            node.times = times;
            days.push(node);
        }
        await DayModel.insertBatch(days);
        return data;
	}

	/**删除数据 */
	async delMeet(id) {
        let where = {
            _id: id
        }
        await MeetModel.del(where);
	}

	/**获取信息 */
	async getMeetDetail(id) {
		let fields = '*';

		let where = {
			_id: id
		}
		let meet = await MeetModel.getOne(where, fields);
		if (!meet) return null;

		let meetService = new MeetService();
		meet.MEET_DAYS_SET = await meetService.getDaysSet(id, timeUtil.time('Y-M-D')); //今天及以后

		return meet;
	}

	/**
	 * 更新富文本详细的内容及图片信息
	 * @returns 返回 urls数组 [url1, url2, url3, ...]
	 */
	async updateMeetContent({
		meetId,
		content // 富文本数组
	}) {

        let where = {
            _id: meetId
        }
        let data = {};
        data.MEET_CONTENT = content;
        await MeetModel.edit(where,data);

	}

	/**
	 * 更新封面内容及图片信息
	 * @returns 返回 urls数组 [url1, url2, url3, ...]
	 */
	async updateMeetStyleSet({
		meetId,
		styleSet
	}) {
        let where = {
            _id: meetId
        }
        let data = {};
        data.MEET_STYLE_SET = styleSet;
        await MeetModel.edit(where,data);

	}

    /** 更新日期设置 */
    async _editDays(meetId, nowDay, daysSetData) {
       return;
    }

	/**更新数据 */
	async editMeet({
		id,
		title,
		typeId,
		typeName,
		order,
		daysSet,
		isShowLimit,
		formSet
	}) {
        let where = {
            _id: id
        }

        let data ={
            MEET_TYPE_ID : typeId,
            MEET_TYPE_NAME :typeName,
            MEET_DAYS : daysSet,
            MEET_TITLE: title,
            MEET_ORDER: order,
            MEET_IS_SHOW_LIMIT: isShowLimit,
            MEET_FORM_SET:formSet
		}
        await MeetModel.edit(where,data);
        let whereDay = {
            DAY_MEET_ID: id
        };
        let days = [];
        for (let k in daysSet) {
            let node = {};
            node.DAY_MEET_ID = id;
            node.day = daysSet[k].day;
            node.dayDesc = daysSet[k].dayDesc;
            let times = [];
            for (let j in daysSet[k].times) {
                let timeNode = {};
                timeNode.mark = daysSet[k].times[j].mark;
                timeNode.start = daysSet[k].times[j].start;
                timeNode.end = daysSet[k].times[j].end;
                timeNode.isLimit = daysSet[k].times[j].isLimit;
                timeNode.limit = daysSet[k].times[j].limit;
                timeNode.status = daysSet[k].times[j].status;
                timeNode.stat = {
                    succCnt: daysSet[k].times[j].stat.succCnt,
                    cancelCnt: daysSet[k].times[j].stat.cancelCnt,
                    adminCancelCnt: daysSet[k].times[j].stat.adminCancelCnt
                };
                times.push(timeNode);
            }
            node.times = times;
            days.push(node);
        }
        await DayModel.del(whereDay);
        await DayModel.insertBatch(days);
	}

	/**预约名单分页列表 */
	async getJoinList({
		search, // 搜索条件
		sortType, // 搜索菜单
		sortVal, // 搜索菜单
		orderBy, // 排序
		meetId,
		mark,
		page,
		size,
		isTotal = true,
		oldTotal
	}) {

		orderBy = orderBy || {
			'JOIN_EDIT_TIME': 'desc'
		};
		let fields = 'JOIN_IS_CHECKIN,JOIN_CODE,JOIN_ID,JOIN_REASON,JOIN_USER_ID,JOIN_MEET_ID,JOIN_MEET_TITLE,JOIN_MEET_DAY,JOIN_MEET_TIME_START,JOIN_MEET_TIME_END,JOIN_MEET_TIME_MARK,JOIN_FORMS,JOIN_STATUS,JOIN_EDIT_TIME';

		let where = {
			JOIN_MEET_ID: meetId,
			JOIN_MEET_TIME_MARK: mark
		};
		if (util.isDefined(search) && search) {
			where['JOIN_FORMS.val'] = {
				$regex: '.*' + search,
				$options: 'i'
			};
		} else if (sortType && util.isDefined(sortVal)) {
			// 搜索菜单
			switch (sortType) {
				case 'status':
					// 按类型
					sortVal = Number(sortVal);
					if (sortVal == 1099) //取消的2种
						where.JOIN_STATUS = ['in', [10, 99]]
					else
						where.JOIN_STATUS = Number(sortVal);
					break;
				case 'checkin':
					// 签到
					where.JOIN_STATUS = JoinModel.STATUS.SUCC;
					if (sortVal == 1) {
						where.JOIN_IS_CHECKIN = 1;
					} else {
						where.JOIN_IS_CHECKIN = 0;
					}
					break;
			}
		}

		return await JoinModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);
	}

	/**预约项目分页列表 */
	async getMeetList({
		search, // 搜索条件
		sortType, // 搜索菜单
		sortVal, // 搜索菜单
		orderBy, // 排序
		whereEx, //附加查询条件
		page,
		size,
		isTotal = true,
		oldTotal
	}) {

		orderBy = orderBy || {
			'MEET_ORDER': 'asc',
			'MEET_ADD_TIME': 'desc'
		};
		let fields = 'MEET_TYPE,MEET_TYPE_NAME,MEET_TITLE,MEET_STATUS,MEET_DAYS,MEET_ADD_TIME,MEET_EDIT_TIME,MEET_ORDER';

		let where = {};
		if (util.isDefined(search) && search) {
			where.MEET_TITLE = {
				$regex: '.*' + search,
				$options: 'i'
			};
		} else if (sortType && util.isDefined(sortVal)) {
			// 搜索菜单
			switch (sortType) {
				case 'status':
					// 按类型
					where.MEET_STATUS = Number(sortVal);
					break;
				case 'typeId':
					// 按类型
					where.MEET_TYPE_ID = sortVal;
					break;
				case 'sort':
					// 排序
					if (sortVal == 'view') {
						orderBy = {
							'MEET_VIEW_CNT': 'desc',
							'MEET_ADD_TIME': 'desc'
						};
					}

					break;
			}
		}

		return await MeetModel.getList(where, fields, orderBy, page, size, isTotal, oldTotal);
	}

	/** 删除 */
	async delJoin(joinId) {
        let where = {
            _id: joinId
        }
        let join = await JoinModel.getOne(where);
        await JoinModel.del(where);
        return this.statJoinCnt2(join.JOIN_MEET_ID, join.JOIN_MEET_TIME_MARK);
	}

	/**修改报名状态 
	 * 特殊约定 99=>正常取消 
	 */
	async statusJoin(admin, joinId, status, reason = '') {
        let where = {
            _id: joinId
        }
        let data = {};
        data.JOIN_EDIT_ADMIN_ID = admin.ADMIN_ID;
        data.JOIN_EDIT_ADMIN_NAME = admin.ADMIN_NAME;
        data.JOIN_EDIT_ADMIN_STATUS = status;
        data.JOIN_EDIT_ADMIN_TIME = timeUtil.time();
        data.JOIN_STATUS = status;
        data.JOIN_REASON = reason;
        await JoinModel.edit(where,data);
        let join = await JoinModel.getOne(where);
        return this.statJoinCnt2(join.JOIN_MEET_ID, join.JOIN_MEET_TIME_MARK);
	}

    // 按时段统计某时段报名情况
    async statJoinCnt2(meetId, timeMark) {
        let whereJoin = {
            JOIN_MEET_TIME_MARK: timeMark,
            JOIN_MEET_ID: meetId
        };
        let ret = await JoinModel.groupCount(whereJoin, 'JOIN_STATUS');

        let stat = { //统计数据
            succCnt: ret['JOIN_STATUS_1'] || 0, //1=预约成功,
            cancelCnt: ret['JOIN_STATUS_10'] || 0, //10=已取消,
            adminCancelCnt: ret['JOIN_STATUS_99'] || 0, //99=后台取消
        };

        let whereDay = {
            DAY_MEET_ID: meetId,
            day: this.getDayByTimeMark(timeMark)
        };
        let day = await DayModel.getOne(whereDay, 'times');
        if (!day) return;

        let times = day.times;
        for (let j in times) {
            if (times[j].mark === timeMark) {
                let data = {
                    ['times.' + j + '.stat']: stat
                }
                await DayModel.edit(whereDay, data);
                return stat;
            }
        }

    }

    // 根据时段标识获取其所在天
    getDayByTimeMark(timeMark) {
        return timeMark.substr(1, 4) + '-' + timeMark.substr(5, 2) + '-' + timeMark.substr(7, 2);
    }

	/**修改项目状态 */
	async statusMeet(id, status) {
        let where = {
            _id: id
        }
        let data = {};
        data.MEET_STATUS = status;
        await MeetModel.edit(where,data);
	}

	/**置顶排序设定 */
	async sortMeet(id, sort) {
        let where = {
            _id: id
        }
        let data = {};
        data.MEET_ORDER = sort;
        await MeetModel.edit(where,data);
	}
}

module.exports = AdminMeetService;